var List = Class.create({	
	initialize: function(data)
	{		
		this.data = data;
		this.surface = Builder.node('div', {id: this.id, className: 'list'});
		
		this.titleBar = Builder.node('div', {className: 'title'});
		this.surface.insert(this.titleBar);
		
		this.bodyDiv = Builder.node('div', {className: 'body'});
		this.surface.insert(this.bodyDiv);
		
		this.az = Builder.node('ul', {className: 'a2z'});
		this.bodyDiv.insert(this.az);
		
		this.listContainer = Builder.node('div', {className: 'datacontainer'});
		this.list = Builder.node('ul', {className: 'data', style: 'position: relative'});
		this.listContainer.insert(this.list);
		this.bodyDiv.insert(this.listContainer);
		
		this.currentPage = 'a';
		
		this.refresh();
		
		this.az.observe('click', function(event) {
			this.showPage(event.target.innerHTML);
		}.bind(this));
		
		this.list.observe('click', this.singleClick.bindAsEventListener(this));
		
		document.observe('list:refresh', function(event){
			this.refresh(event.memo == true);
		}.bindAsEventListener(this));
	},
	
	refresh: function(preventScroll)
	{
		this.selected = new Object();
		this.selected_count = 0;
		
		if(!preventScroll)
			this.current_index = 0;
		
		this.renderA2Z();	
		this.renderList(preventScroll);
		this.updateTitle();
	},
	
	renderA2Z: function()
	{
		this.az.update();
		
		for(var i=65; i<=90; i++)
		{
			var c = String.fromCharCode(i).toLowerCase();
			var node = Builder.node('li', {id: this.tag+'-az-'+c, title: c.toUpperCase()+"'s ("+this.data.az_indexes[c].length+" items)"}, c);
			
			if(this.data.az_indexes[c].length)
				node.addClassName('enabled');
				
			if(c == this.currentPage)
				node.addClassName('selected');
			
			this.az.insert(node);
		}
		
		this.az.insert(Builder.node('li', {}, '#'));
	},
	
	updateTitle:function()
	{
		this.titleBar.update("List");
	},
	
	showPage: function(page)
	{
		if(this.currentPage != page)
		{
			if(this.data.az_indexes[page].length)
			{
				this.currentPage = page;
				this.refresh();
				this.listContainer.scrollTop = 0;
				
				this.updateTitle();
			}
		}
	},
	
	selectRowWithIndex: function(index)
	{
		var li = this.list.childElements()[index];
		this.selectRow(li);
	},
	
	selectRow: function(li, addSelection)
	{
		var id = li.id.split('-').last();
		var index = /row([0-9]+)/.exec(li.className);
		
		if(index)
			index = parseInt(index[1]);
		
		if(!addSelection)
		{
			for(i in this.selected)
			{
				if(this.selected[i])
					$(this.tag+'-listitem-'+i).removeClassName('selected');
			}
			
			this.selected = new Object();
			this.selected_count = 0;
		}
	
		this.selected[id] = true;
		this.selected_count++;
		this.current_index = index;
		
		li.addClassName('selected');
	},
	
	unselectRow: function(li)
	{
		var index = li.id.split('-').last();
		this.selected[index] = false;
		this.selected_count--;
		li.removeClassName('selected');
	},
	
	singleClick: function(event)
	{
		var elem = this.getListItemFromEvent(event);
		var id = elem.id.split('-').last();
		
		if(this.selected[id])
			this.unselectRow(elem);
		else
			this.selectRow(elem, (event.metaKey || event.ctrlKey));
	},
	
	keyPress: function(event)
	{
		if(event.keyCode == 38 /* UP */ || event.keyCode == 40 /* DOWN */)
		{
			// Move up or down
			var prev = this.current_index;
			this.current_index += (event.keyCode==38 ? -1 : 1);
			
			// range check
			if(this.current_index < 0)
				this.current_index = 0;
				
			if(this.current_index > this.list.childElements().length)
				this.current_index = this.list.childElements().length-1;
			
			if(event.shiftKey)
			{
				var c_li = this.list.childElements()[this.current_index];
				if(c_li.hasClassName('selected'))
				{
					var p_li = this.list.childElements()[prev];
					this.unselectRow(p_li);
				}
			}

			var li = this.list.childElements()[this.current_index];
			this.selectRow(li, event.shiftKey);
			
			// Make sure the new item is visible
			if(li.offsetTop + li.getHeight() > this.listContainer.getHeight() + this.listContainer.scrollTop)
			{
				this.listContainer.scrollTop = li.offsetTop + li.getHeight() - this.listContainer.getHeight();
			}
			else if(li.offsetTop < this.listContainer.scrollTop)
			{
				this.listContainer.scrollTop = li.offsetTop;
			}
		}
	},
	
	getSurface: function()
	{
		return this.surface;
	},
	
	getListItemFromEvent: function(event)
	{
		var elem = event.target;
		
		if(elem.tagName != 'LI')
			elem = elem.up('li');
			
		return elem;
	}
})